package com.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author: 一个小菜逼
 * @Date: 2020/4/28
 */
public class MyReflect {

    private MyReflect(String s){
        System.out.println("利用String类型的构造器生成对象..."+s);
    }

    public MyReflect(){
        System.out.println("利用无参构造器生成对象...");
    }

    public static void main(String[] args) {
        try {

            //获取类对象；获取类对象有3种方式
            //1.类名.class，直接获取类对象
            //2.Class.forName(".class文件路径")，通过加载文件路径来获取
            //3.实例对象.getClass，一般不用这个，本来就是为了得到实例对象才使用的反射
            //用实例对象得到反射对象就显得本末倒置了，第2种方式应该是用的最多的
            Class<MyReflect> clazz01= MyReflect.class;
            Class<?> clazz02 = Class.forName("com.reflect.MyReflect");


            //1.1.getConstuctor默认是直接调用无参构造器来生成对象
            Constructor<MyReflect> constructor01 = clazz01.getConstructor();
            MyReflect o = (MyReflect)constructor01.newInstance();
            System.out.println(o);

            //1.2.getDeclaredConstructor声明使用特定类型的构造器来生成对象
            Constructor<MyReflect> declaredConstructor01 = clazz01.getDeclaredConstructor(String.class);
            MyReflect myReflect = declaredConstructor01.newInstance("类名.class方法");
            System.out.println(myReflect);


            //2.1.getConstuctor默认是直接调用无参构造器来生成对象
            Constructor<?> constructor02 = clazz02.getConstructor();
            MyReflect o1 = (MyReflect)constructor02.newInstance();
            System.out.println(o1);

            //2.2.getDeclaredConstructor声明使用特定类型的构造器来生成对象
            Constructor<?> declaredConstructor0102 = clazz02.getDeclaredConstructor(String.class);
            MyReflect sucessfull = (MyReflect)declaredConstructor0102.newInstance("类名.class方法");
            System.out.println(sucessfull);


            //获取所有的构造器，包括public和private
            Constructor<?>[] declaredConstructors = clazz01.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println(declaredConstructor);
            }

            //获取所有的非private类型的属性
            Field[] fields = clazz01.getFields();
            //获取指定名字的属性
            Field field = clazz01.getField("");
            //获取所有的属性public和private类型的都会获取到
            Field[] declaredFields = clazz01.getDeclaredFields();
            //获取指定类型的属性，不管是public还是private都可以获取到
            Field declaredField = clazz01.getDeclaredField("");
            //将属性的安全检查关闭，意味着，通过反射也可以调用类的私有属性、私有构造器、私有方法
            //当然构造器对象、方法对象也要设置这个为true
            declaredField.setAccessible(true);

            //获取指定名字的非private的方法
            Method method = clazz01.getMethod("");
            //获取多有非private类型的方法
            Method[] methods = clazz01.getMethods();
            //获取指定名字的方法，不管是private或者是public
            Method declaredMethod = clazz01.getDeclaredMethod("");
            //获取所有的方法，不管是private或者是public
            Method[] declaredMethods = clazz01.getDeclaredMethods();


        }catch (Exception e){
         e.printStackTrace();
        }
    }

    @Override
    public String toString() {
        return "打印MyReflect对象...";
    }
}
